/**
 * @desc 菜单列表组件
 * */
import React from "react";
import { connect } from "react-redux";
import { Space, Table, Tag, Typography, TreeSelect } from "antd";
import TheDialog from "@/components/TheDialog";
import MenuDetails from "./component/details";
import MenuPower from "./component/power";
import MenuAdd from "./component/add";
import MenuUpdate from "./component/update";
import TheButton from "@/components/TheButton";
import SearchForm from "./component/searchForm";
import { getTreeData, sortTree } from "@/utils/getTreeData"
import paramsFilter from '@/utils/paramsFilter'
import { apiPage, apiMenuChangeState, apiMenuRemove, apiDetails, apiEdit } from "@/request/system/menu"
import TreeMenu from "./component/treeMenu"

const { Paragraph } = Typography;
class Menu extends React.Component {
  state = {
    list: [],//扁平化菜单数据
    treeDataSource: [],
    treeValue: undefined,
    treeVisibility: false,
    maxAddMenuLength: 3,//最大可以添加几级菜单
    dataSource: [],
    dialogType: "add",
    title: "新增",
    loading: false,
    dialogStatus: false,
    total: 10,
    btnLoading: false,
    storeMenuId: null,//菜单storeMenuId
    nowRowData: null,
    detailsData: null,
    searchParams: {
      name: 1,
      menuAreaCode: ''
    },
    columns: [
      {
        title: "菜单名称",
        dataIndex: "menuName",
        key: "menuName",
      },
      {
        title: "路由名称",
        align: 'center',
        dataIndex: "menuUrl",
        key: "menuUrl",
        render: (text, record) => {
          if (record.menuLevel === 2) {
            return <Paragraph style={{ marginBottom: 0 }} copyable>{text}</Paragraph>
          } else {
            return text
          }
        }
      },
      {
        title: "菜单等级",
        align: 'center',
        dataIndex: "menuLevel",
        key: "menuLevel",
        render: (text) => {
          return <Tag color={["red", "gold", "green", "blue", "cyan"][text]}>{text}</Tag>
        }
      },
      {
        title: "菜单图标",
        align: 'center',
        render: (text, record) => (
          <span className={[`iconfont ${record.menuIcon}`]} />
        )
      },
      {
        title: "菜单状态",
        align: 'center',
        render: (text, record) => (
          <>
            {record.status === 'Y' && <Tag color="green">启用</Tag>}
            {record.status === 'N' && <Tag color="red">停用</Tag>}
          </>
        )
      },
      {
        title: "排序",
        dataIndex: "sorted",
        key: "sorted"
      },
      {
        title: "操作",
        width: 270,
        render: (text, record) => {
          return <Space size="small">
            {(record.storeMenuId === -1 || record.menuLevel !== this.state.maxAddMenuLength) &&
              <TheButton hasPermi={['settings:menu:add']} onClick={() => this.dialogChange('add', record)}>新增</TheButton>}
            {
              record.storeMenuId !== -1 && <>
                <TheButton hasPermi={['settings:menu:edit']}
                  onClick={() => this.dialogChange('edit', record)}>修改</TheButton>
                <TheButton hasPermi={['settings:menu:view']}
                  onClick={() => this.dialogChange('details', record)}>查看</TheButton>
                <TheButton haspermi={['set:menu:move']}
                  onClick={() => this.showTree(record.storeMenuId)}>移动</TheButton>
                <TheButton
                  hasPermi={['settings:menu:state']}
                  onClick={() => this.changeState(record)}>{record.status === 'Y' ? '停用' : '启用'}</TheButton>
                {!record.hasOwnProperty('children') &&
                  <TheButton hasPermi={['settings:menu:power']}
                    onClick={() => this.dialogChange('power', record)}>设置权限</TheButton>}
                <TheButton hasPermi={['settings:menu:delete']} onClick={() => this.del(record.storeMenuId)}>删除</TheButton>
              </>
            }
          </Space>
        }
      }
    ]
  };

  async componentDidMount() {
    await this.getList()
  }

  //
  /**
   * @desc 分页初始化
   * */
  init = () => {
    this.setState({
      pageParams: {
        pageNo: 1,
        pageSize: 10
      }
    });
  };

  /**
   * @desc 获取详情数据
   * @params string {id} 当前选中数据选主键
   * */
  getDetailsData = async (id) => {
    const res = await apiDetails({ storeMenuId: id });
    if (res.code === 0) {
      this.setState({
        detailsData: res.data
      })
    }
  };


  /**
   * @desc 表格操作列功能函数
   * @params object {value} 当前操作列数据
   * */
  changeState = async (value) => {
    const { storeMenuId, status } = value
    const label = status === "Y" ? "停用" : "启用"
    React.$confirm({
      title: "警告",
      content: `确定要${label}吗？`,
      onOk: async () => {
        const res = await apiMenuChangeState({ storeMenuId: storeMenuId, status: status === "Y" ? "N" : "Y" })
        if (res.code === 0) {
          React.$message({
            type: "success",
            content: "操作成功"
          });
          await this.getList()
        }
      }
    });

  }
  /**
   * @desc 表格操作列功能函数
   * @params string {type} 操作类型
   * @params object {data} 当前操作的数据
   * */
  dialogChange = async (type, data) => {
    let title = '新增';
    switch (type) {
      case 'add':
      default:
        title = '新增';
        break;
      case 'edit':
        await this.getDetailsData(data.storeMenuId)
        title = '编辑';
        break;
      case 'details':
        await this.getDetailsData(data.storeMenuId)
        title = '查看';
        break;
      case 'power':
        title = '设置菜单权限';
        break;
    }
    this.setState({
      title: title,
      dialogType: type,
      dialogStatus: true,
      storeMenuId: data.storeMenuId,
      nowRowData: data
    });
  }
  /**
   * @desc 获取列表数据
   * @params object {params} 分页参数
   * */
  getList = async (params) => {
    this.setState({ loading: true })
    const res = await apiPage(params)
    if (res.code === 0) {
      this.setState({
        list: res.data,//原菜单数据
        dataSource: [{
          menuParentId: -1,
          storeMenuId: -1,
          menuName: '主菜单',
          menuAreaCode: '全局作用域',
          key: 0,
          menuComponent: '/',
          menuLevel: 0,
          menuIcon: 'PicCenterOutlined',
          status: 'Y',
          children: sortTree(getTreeData(res.data))
        }]
      })
    }
    this.setState({ loading: false })
  }
  /**
   * @desc 删除事件
   * @params string {id} 删除数据主键
   * */
  del = async (id) => {
    React.$confirm({
      title: "警告",
      content: "确定要删除吗？",
      onOk: async () => {
        const data = await apiMenuRemove({ storeMenuId: id })
        if (data.code === 0) {
          React.$message({
            type: "success",
            content: "删除成功"
          });
          await this.getList()
        }
      }
    });
  };

  /**
   * @desc 分页筛选
   * @params object {values} 筛选参数对象
   * */
  search = async values => {
    this.init();
    values = paramsFilter(values);
    await this.getList(values)
  };
  /**
   * @desc 弹窗关闭事件
   * */
  dialogClose = () => {
    this.setState({ dialogStatus: false });
  };

  treeVisibilityClose = () => {
    this.getList()
    this.setState({
      treeVisibility: false
    })
  }
  /**
   * @desc: 过滤树节点
   * @date: 2024-05-16
   * */
  filterTreeArray(tree, storeMenuId) {
    return tree.filter(item => {
      return item.storeMenuId != storeMenuId
    }).map(item => {
      item = Object.assign({}, item)
      if (item.children) {
        item.children = this.filterTreeArray(item.children, storeMenuId)
      }
      return item
    })
  }
  showTree = (storeMenuId) => {
    const treeDataSource = this.filterTreeArray(this.state.dataSource, storeMenuId)

    this.setState({
      storeMenuId,
      treeDataSource,
      treeVisibility: true,
      treeValue: null
    })
  }

  treeSelectChange = (newValue) => {
    this.setState({
      treeValue: newValue
    })
  }
  handleOk = async () => {
    const parentData = [...this.state.list, {
      menuParentId: -1,
      storeMenuId: -1,
      menuName: '主菜单',
      menuLevel: 0,
    }].filter(item => item.storeMenuId == this.state.treeValue)
    const menuLevel = parentData[0].menuLevel + 1
    if (menuLevel > 3) return React.$message({
      type: 'error',
      content: '仅支持三级菜单'
    })
    const res = await apiEdit({
      storeMenuId: this.state.storeMenuId,
      menuParentId: this.state.treeValue,
      menuLevel
    })
    if (res.code == 0) {
      React.$message({
        type: 'success',
        content: '修改成功'
      })
      this.setState({
        treeVisibility: false
      })
      this.getList()
    }
  }

  render() {
    const {
      treeVisibility,
      dataSource,
      columns,
      loading,
      dialogStatus,
      title,
      dialogType,
      storeMenuId,
      btnLoading,
      nowRowData,
      treeValue,
      treeDataSource,
      detailsData
    } = this.state;
    return (
      <div className={"p-layout-box"}>
        {/*顶部搜索区域*/}
        <div className={"p-search-box"} >
          <SearchForm
            onFinish={this.search}
            add={() => this.dialogChange('add')} />
        </div>
        {/*表格区域*/}
        <div className={"p-layout-content"}>
          <div style={{ flex: 1 }}>
            <Table
              bordered
              expandable={{ defaultExpandedRowKeys: [0] }}
              defaultExpandedRowKeys
              loading={loading}
              pagination={false}
              dataSource={dataSource}
              columns={columns} />
          </div>
        </div>
        {/* {菜单树弹窗} */}
        <TheDialog
          visible={treeVisibility}
          title={'菜单调整'}
          handleCancel={this.treeVisibilityClose}
          handleOk={this.handleOk}
        >
          <TreeSelect
            showSearch
            style={{
              width: '100%',
            }}
            value={treeValue}
            dropdownStyle={{
              maxHeight: 400,
              overflow: 'auto',
            }}
            fieldNames={{ label: 'menuName', value: 'storeMenuId' }}
            placeholder="请选择"
            allowClear
            treeDefaultExpandAll
            onChange={this.treeSelectChange}
            treeData={treeDataSource}
          />
        </TheDialog>
        {/*增删改查弹窗*/}
        <TheDialog
          visible={dialogStatus}
          title={title}
          handleCancel={this.dialogClose}
          footer={null}>
          {
            /* 新增弹窗*/
            dialogType === 'add' &&
            <MenuAdd btnLoading={btnLoading}
              nowRowData={nowRowData}
              handleCancel={this.dialogClose}
              getList={this.getList} />
          }
          {
            /* 编辑弹窗*/
            dialogType === 'edit' &&
            <MenuUpdate btnLoading={btnLoading}
              nowRowData={nowRowData}
              detailsData={detailsData}
              getList={this.getList}
              handleCancel={this.dialogClose} />
          }
          {
            /* 查看弹窗*/
            dialogType === 'details' &&
            <MenuDetails
              id={storeMenuId}
              detailsData={detailsData}
              handleCancel={this.dialogClose} />
          }
          {
            /* 设置菜单权限*/
            dialogType === 'power' &&
            <MenuPower storeMenuId={storeMenuId} handleCancel={this.dialogClose} handleOk={this.dialogSave} />
          }
        </TheDialog>
      </div>
    );
  }
}

const mapStateToProps = state => {
  return {
    user: state.user,
    areaCode: state.areaCodeSelectValue,
  };
};
export default connect(mapStateToProps, null)(Menu);
